package com.ruifu.proj.service.impl;

import com.fhzncloud.cloud.common.security.service.CloudUser;
import com.ruifu.common.po.PmPtMain;
import com.ruifu.common.po.PmPtObject;
import com.ruifu.common.utils.BeanConverter;
import com.ruifu.proj.dto.ptobject.PmPtCopyInsertObjectDTO;
import com.ruifu.proj.dto.ptobject.PmPtInsertObjectDTO;
import com.ruifu.proj.mapper.PmPtMainMapper;
import com.ruifu.proj.mapper.PmPtObjectMapper;
import com.ruifu.proj.service.PmPtMainService;
import com.ruifu.proj.service.PmPtObjectService;
import com.ruifu.proj.vo.pmPtObject.PmPtObjectDocVerVO;
import com.ruifu.proj.vo.pmPtObject.PmPtObjectDoccVO;
import com.ruifu.proj.vo.pmPtObject.PmPtObjectResultVO;
import com.ruifu.proj.vo.ptmain.PmPtMainIOVO;
import com.ruifu.proj.vo.ptmain.PmPtMainTaskVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author nyr
 * @create 2019/9/18
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PmPtObjectServiceImpl implements PmPtObjectService {

    @Autowired(required = false)
    private PmPtObjectMapper pmPtObjectMapper;

    @Autowired(required = false)
    private PmPtMainMapper pmPtMainMapper;

    @Autowired(required = false)
    private PmPtMainService pmPtMainService;


    /**
     * 添加输入(输出)文档类型和输入(输出)文档
     *
     * @param pmPtInsertObjectDTO
     * @param cloudUser
     * @return
     */
    @Override
    public void insert(PmPtInsertObjectDTO pmPtInsertObjectDTO, CloudUser cloudUser) {
        /*DTO转PO*/
        PmPtObject pmPtObject = BeanConverter.copyProperties(pmPtInsertObjectDTO, PmPtObject.class);

        //2020.5.26 插入之前查询是否已经有同样的文档存在，存在则不允许插入
        if (pmPtObject.getPoObjId()!=null){
            PmPtObject object= pmPtObjectMapper.findByPtIdAndPoIOTypeAndPoObjId(pmPtObject.getPoPtId(),
                    pmPtObject.getPoIOType(),
                    pmPtObject.getPoObjId(),
                    pmPtObject.getPoObjTypeId(),
                    cloudUser);
            if (object!=null){
                throw new RuntimeException("已有相同文档存在，请不要重复添加！");
            }
        }
        //存储到数据库
        pmPtObjectMapper.insert(pmPtObject, cloudUser);
    }

    /**
     * 批量删除输入(输出)文档类型和输入(输出)文档
     *
     * @param poIds
     * @return
     */
    @Override
    public void delete(Long[] poIds, CloudUser cloudUser) {
        //遍历id数组
        for (Long poId : poIds) {
            //根据Id查询PO对象
            PmPtObject pmPtObject = pmPtObjectMapper.findById(poId);
            //修改删除标记
            pmPtObject.setPoDelFlag(true);
            //更新到数据库
            pmPtObjectMapper.update(pmPtObject, cloudUser);
        }
    }

    /**
     * 根据选择的任务来源名称查询该任务的输出文档将类型相同的作为该任务的输入文档
     *
     * @param pmPtCopyInsertObjectDTO
     * @param cloudUser
     */
    @Override
    public void insertCopyByPtCode(PmPtCopyInsertObjectDTO pmPtCopyInsertObjectDTO, CloudUser cloudUser) {
        /*查询当前任务的输出文档*/
        //根据根项目id查询子任务列表
        List<PmPtMainTaskVO> ptMainTaskVOS = pmPtMainService.findTaskByPtId(pmPtCopyInsertObjectDTO.getBastPoPtId());
        //声明来源任务对象
        PmPtMainTaskVO sourcePmPtMain = null;
        //遍历子任务列表
        for (PmPtMainTaskVO ptMainTaskVO : ptMainTaskVOS) {
            //判断用户输入的名字是否在当前项目的子任务列表中
            if (ptMainTaskVO.getPtCode().equals(pmPtCopyInsertObjectDTO.getPtCode())) {
                //存在，将当前任务赋值给来源任务对象并退出循环
                sourcePmPtMain = ptMainTaskVO;
                break;
            }
        }
        //来源任务非空校验
        if (sourcePmPtMain == null) {
            throw new RuntimeException("当前来源任务编号不存在当前项目中");
        }
        /*修改当前输入文档类型的来源*/
        //根据id查询当前输入文档类型
        PmPtObject pmPtObjectType = pmPtObjectMapper.findById(pmPtCopyInsertObjectDTO.getPoId());
        //判断该文档类型来源是否已经拥有来源
        if (pmPtObjectType.getPoSourceId() != null) {
            /*拥有来源*/
            //查询该任务的输入文档的记录列表
            List<PmPtObject> pmPtObjectList = pmPtObjectMapper.findByPtIdAndPoIOType(pmPtCopyInsertObjectDTO.getPoPtId(), "I", false, cloudUser);
            //遍历该集合
            for (PmPtObject pmPtObject : pmPtObjectList) {
                //判断来源是否来自于原来源任务id
                if (pmPtObject.getPoSourceId().longValue() == pmPtObjectType.getPoSourceId().longValue()) {
                    //修改删除标记
                    pmPtObject.setPoDelFlag(true);
                    //保存到数据库
                    pmPtObjectMapper.update(pmPtObject, cloudUser);
                }
            }
        }
        //设置该类型来源
        pmPtObjectType.setPoSourceId(sourcePmPtMain.getPtId());
        //更新到数据库
        pmPtObjectMapper.update(pmPtObjectType, cloudUser);
        /*复制来源的输出文档*/
        //定义输出集合
        List<PmPtObject> ptObjectList = new ArrayList<>();
        //递归根据任务id去查询当前任务的输出文档
        this.recursionIODoccTypeOrIODocVer(sourcePmPtMain.getPtId(), "O", false, ptObjectList, cloudUser);
        /*插入类型相同的文档*/
        //遍历获得类型相同的输出文档
        for (PmPtObject pmPtObject : ptObjectList) {
            //筛选类型相同的
            if (pmPtObject.getPoObjTypeId().longValue() == pmPtObjectType.getPoObjTypeId().longValue()) {
                //清空主键
                pmPtObject.setPoId(null);
                //设置所属任务
                pmPtObject.setPoPtId(pmPtCopyInsertObjectDTO.getPoPtId());
                //设置来源任务
                pmPtObject.setPoSourceId(sourcePmPtMain.getPtId());
                //设置为输出文档
                pmPtObject.setPoIOType("I");
                //插入到数据库中
                pmPtObjectMapper.insert(pmPtObject, cloudUser);
            }
        }
    }

    /**
     * 文档输入
     *
     * @param ptId
     * @param poIOType
     * @param cloudUser
     * @return
     */
    @Override
    public PmPtObjectResultVO findByPoPtIdAndPoIOType(Long ptId, String poIOType, CloudUser cloudUser) {
        /*查询文档类型列表*/
        //定义文档类型集合
        List<PmPtObject> pmPtObjectDoccList = new ArrayList<>();
        //递归查询子任务的文档类型
        this.recursionIODoccTypeOrIODocVer(ptId, poIOType, true, pmPtObjectDoccList, cloudUser);
        /*PO转VO*/
        List<PmPtObjectDoccVO> pmPtObjectDoccVOList = BeanConverter.copyList(pmPtObjectDoccList, PmPtObjectDoccVO.class);
        /*查询文档列表*/
        //定义文档集合
        List<PmPtObject> pmPtObjectDocVerList = new ArrayList<>();
        //递归查询子任务的文档
        this.recursionIODoccTypeOrIODocVer(ptId, poIOType, false, pmPtObjectDocVerList, cloudUser);
        /*PO转VO*/
        List<PmPtObjectDocVerVO> pmPtObjectDocVerVOList = BeanConverter.copyList(pmPtObjectDocVerList, PmPtObjectDocVerVO.class);
        /*设置返回结果*/
        //定义结果VO对象
        PmPtObjectResultVO pmPtObjectResultVO = new PmPtObjectResultVO();
        //遍历文档类型集合
        for (PmPtObjectDoccVO pmPtObjectDoccVO : pmPtObjectDoccVOList) {
            if (pmPtObjectDoccVO.getPoSourceId() != null) {
                PmPtMain sourcePmPtMain = pmPtMainMapper.findById(pmPtObjectDoccVO.getPoSourceId());
                /*po转vo*/
                PmPtMainIOVO sourcePmPtMainVO = BeanConverter.copyProperties(sourcePmPtMain, PmPtMainIOVO.class);
                //设置文档类型来源
                pmPtObjectDoccVO.setSourcePmPtMain(sourcePmPtMainVO);
            }
        }
        //存放文档类型集合
        pmPtObjectResultVO.setPmPtObjectDoccList(pmPtObjectDoccVOList);
        //遍历文档集合
        for (PmPtObjectDocVerVO pmPtObjectDocverVO : pmPtObjectDocVerVOList) {
            if (pmPtObjectDocverVO.getPoSourceId() != null) {
                PmPtMain sourcePmPtMain = pmPtMainMapper.findById(pmPtObjectDocverVO.getPoSourceId());
                /*po转vo*/
                PmPtMainIOVO sourcePmPtMainVO = BeanConverter.copyProperties(sourcePmPtMain, PmPtMainIOVO.class);
                //设置文档来源于
                pmPtObjectDocverVO.setSourcePmPtMain(sourcePmPtMainVO);
            }
        }

        //存放文档集合
        pmPtObjectResultVO.setPmPtObjectDocverList(pmPtObjectDocVerVOList);
        return pmPtObjectResultVO;
    }

    /**
     * 递归查询
     *
     * @param ptId           任务id
     * @param poIOType       输入/输出文档
     * @param isObjTypeFlag  是否查询类型
     * @param pmPtObjectList 要装载的集合
     * @param cloudUser
     */
    public void recursionIODoccTypeOrIODocVer(Long ptId, String poIOType, Boolean isObjTypeFlag, List<PmPtObject> pmPtObjectList, CloudUser cloudUser) {
        //查询当前任务所有的I/O记录
        List<PmPtObject> list = pmPtObjectMapper.findByPtIdAndPoIOType(ptId, poIOType, isObjTypeFlag, cloudUser);
        //将记录添加到装在集合中
        pmPtObjectList.addAll(list);
        /*递归体*/
        //根据任务id查询子任务
        List<PmPtMain> pmPtMainList = pmPtMainMapper.findByPtPId(ptId);
        //遍历子任务
        for (PmPtMain pmPtMain : pmPtMainList) {
            //递归
            this.recursionIODoccTypeOrIODocVer(pmPtMain.getPtId(), poIOType, isObjTypeFlag, pmPtObjectList, cloudUser);
        }
    }

    @Override
    public List<PmPtObjectDocVerVO> findObjectByPtId(Long ptId, String poIOType, Long poObjTypeId,CloudUser cloudUser) {
        boolean isObjTypeFlag=false;
        List<PmPtObject> objectList = pmPtObjectMapper.findByPtIdAndPoIOType(ptId, poIOType, isObjTypeFlag, cloudUser);
        objectList.removeIf(x-> !x.getPoObjTypeId().equals(poObjTypeId));
        return BeanConverter.copyList(objectList, PmPtObjectDocVerVO.class);
    }




    @Override
    public void updatePoIsMustByPoId(Long poId, Boolean isMust, CloudUser cloudUser) {
        //根据id查询记录
        PmPtObject pmPtObject = pmPtObjectMapper.findById(poId);
        //修改必须字段
        pmPtObject.setPoIsMust(isMust);
        //更新数据库
        pmPtObjectMapper.update(pmPtObject, cloudUser);
    }

    @Override
    public void insertPL(List<PmPtInsertObjectDTO> pmPtInsertObjectDTOList, CloudUser cloudUser) {
        for (PmPtInsertObjectDTO pmPtInsertObjectDTO : pmPtInsertObjectDTOList) {
            this.insert(pmPtInsertObjectDTO, cloudUser);
        }
    }


}
